package com.bingo.generate.cli.Cmds;


import com.bingo.generate.comm.entity.ColInfo;
import com.bingo.generate.comm.service.GenerateDbService;
import com.bingo.generate.comm.util.FmUtil;
import com.bingo.generate.comm.util.JdbcUtil;
import com.bingo.generate.comm.util.PathUtils;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;

import java.nio.file.Paths;
import java.util.*;
import java.util.stream.Collectors;

/**
 * ClassName
 * Description
 * Create by lc
 * Date 2021/7/16 10:03
 * 生成php代码的生成器
 *
 * 重要方法:
 * createInsertFtl: 根据传入的表名和字段名称，生成对应的php添加代码
 * createUpdFtl:    根据传入的表名和字段名称，生成对应的php修改数据库代码
 *
 */
public class PhpCodeCmd {

    public static void main(String[] args) {
        PathUtils.cofDir= Paths.get("C:\\temp\\gererate-path");
        JdbcUtil.loadConfig();

        String str="id, user_id, category_id, type, region, year, title, subtitle, thumb, images, url, intro, duration, score, release_date, release_address, tags, actor_list, has_subtitle, view_num, like_num, comment_num, share_num, collect_num, relate_id, status, updated_at, created_at, source_type, payment_type, resolve_power, serial_code, file_size, copy_num, copy_use_id, approve_status, approve_time, approve_user_id";
        /*
        //addMapArr(str);

        tmpGenArrConst("movie",str);*/
        //  tmpGenArrConstOne("type","分类","MOVIE:MOVIE:电影 TV:TV:剧集 3:OTHER:其他");
        //  tmpGenArrConstOne("has_subtitle","是否有字幕","1：有 2：无");
        /*tmpGenArrConstOne("source_type_op","视频来源","0:other_platform:平台下发 1:user:用户上传 2:system:后台创建");
        tmpGenArrConstOne("payment_type_op","付费类型","0:free:免费 1:vip:会员 2:charge:付费 3:limited_exemption:限免");
        tmpGenArrConstOne("approve_status_op","审核状态","0:wait:未审批 1:ok:通过 2:fail:未曾通过");*/

        //  tmpGenArrConstOne("","");

    }

    //  输入例子year, title, subtitle, url, intro, score, release_address, tags, actor_list, view_num, like_num, comment_num, share_num, collect_num, copy_num
    public static void addQuote(String str){
        String[] nameArr = toVarArr(str);
        if (nameArr == null) return;
        StringBuilder strBud=new StringBuilder();
        for (String s : nameArr) {
            strBud.append(String.format(", \"%s\"",s));
        }
        if(strBud.length()>1){
            strBud.deleteCharAt(0);
        }
        System.out.println(strBud.toString());;

    }

    //  变成映射数组/关联数组
    public static void addMapArr(String str){
        String[] nameArr = toVarArr(str);
        if (nameArr == null) return;
        StringBuilder strBud=new StringBuilder();
        for (String s : nameArr) {
            strBud.append(String.format(", \"%s\"=>[]",s));
        }
        if(strBud.length()>1){
            strBud.deleteCharAt(0);
        }
        System.out.println(strBud.toString());;

    }

    private static String[] toVarArr(String str) {
        if(StringUtils.isBlank(str)){
            return null;
        }
        str = str.replace(","," ");
        //  两个空格合并为一个空格
        while (str.indexOf("  ")!=-1){
            str = str.replace("  "," ");
        }
        String[] nameArr = str.split(" ");
        return nameArr;
    }

    //  根据传入的字段名生成php的数组常量
    public static List<ColInfo> listColInfo(String tbKey, String str){
        List<String> tmpList = Arrays.asList(toVarArr(str));
        Set<String> statusColSet=new HashSet(tmpList);
        List<ColInfo> list= GenerateDbService.ins.searchCols(null,tbKey);
        List<ColInfo> myList=new ArrayList<>();
        for (ColInfo colInfo : list) {
            if (!statusColSet.contains(colInfo.getColName())){
                continue;
            }
            myList.add(colInfo);
        }
        return myList;
    }

    //  dsl:[值:英文名:中文名 ...] 多个值之间用空格隔开
    public static void tmpGenArrConstOne(String name,String comment,String dsl){
        if(dsl.indexOf(" ")==-1){
            throw new RuntimeException("请你保证有多个值");
        }
        List<StatusConst> list= StatusConst.create(dsl);
        //  生成常量
        StringBuilder strBud=new StringBuilder();
        for (StatusConst statusConst : list) {
            String constName=name+"_"+statusConst.getName();
            statusConst.setConstName(constName.toUpperCase());
            strBud.append(String.format("const %s = %s ;\t//\t%s的常量:%s\n",statusConst.getConstName(),statusConst.val,comment,statusConst.meaning));
        }

        //  生成类型
        strBud.append("// \t"+comment+"\n");
        strBud.append("public static $"+name).append("=[");
        for (StatusConst statusConst : list) {
            strBud.append("\n\t").append("'"+statusConst.getName()+"' => [")
                    .append("\n\t\t").append(String.format("'key' => self::%s,",statusConst.getConstName()))
                    .append("\n\t\t").append(String.format("'value' => '%s',",statusConst.getMeaning()))
                    .append("\n\t],")
            ;
        }
        strBud.deleteCharAt(strBud.length()-1);
        strBud.deleteCharAt(strBud.length()-4);
        strBud.append("\n];");
        System.out.println(strBud.toString());
    }

    //  dsl:[值:英文名:中文名 ...] 多个值之间用空格隔开  生成简洁值
    public static void tmpGenArrConstOne2(String name,String comment,String dsl){
        if(dsl.indexOf(" ")==-1){
            throw new RuntimeException("请你保证有多个值");
        }
        List<StatusConst> list= StatusConst.create(dsl);
        //  生成常量
        StringBuilder strBud=new StringBuilder();
        for (StatusConst statusConst : list) {
            String constName=name+"_"+statusConst.getName();
            statusConst.setConstName(constName.toUpperCase());
            strBud.append(String.format("const %s = %s ;\t//\t%s的常量:%s\n",statusConst.getConstName(),statusConst.val,comment,statusConst.meaning));
        }

        //  生成类型
        strBud.append("// \t"+comment+"\n");
        strBud.append("public static $"+name).append("_op=[");
        for (StatusConst statusConst : list) {
            strBud.append("\n\t").append(String.format("self::%s => '%s'"
                    ,statusConst.getConstName()
                    ,statusConst.getMeaning()))
                    /*.append("\n\t\t").append(String.format("'key' => self::%s,",statusConst.getConstName()))
                    .append("\n\t\t").append(String.format("'value' => '%s',",statusConst.getMeaning()))*/
                    .append(" ,")
            ;
        }
        strBud.deleteCharAt(strBud.length()-1);
        //strBud.deleteCharAt(strBud.length()-4);
        strBud.append("\n];");
        System.out.println(strBud.toString());
    }

    //  生成col字段常量
    public static void genColConstOne(List<String> cols){
        StringBuilder strBud = new StringBuilder();
        for (String col : cols) {
            strBud.append(String.format("public const COL_%s='%s';\n",col.toUpperCase(),col));
        }
        System.out.println(strBud.toString());
    }

    //  生成col字段常量
    public static void genColConstCol(List<ColInfo> cols){
        StringBuilder strBud = new StringBuilder();
        int i=1;
        for (ColInfo col : cols) {
            strBud.append(String.format("public const COL_%s='%s';\t//\t%s: %s\n",col.getColName().toUpperCase(),col.getColName(),i,col.getComment()));
            i++;
        }
        System.out.println(strBud.toString());
    }

    public static void createInsertFtl(String entityName,List<ColInfo> colInfos){
        Map<String,Object> param=new HashMap<>();
        param.put("modelName",entityName);
        param.put("cols",colInfos);
        FmUtil.print("phpTipsAdd.ftl",param);
    }

    public static void createUpdFtl(String tbName,List<ColInfo> colInfos){
        Map<String,Object> param=new HashMap<>();
        param.put("tbName",tbName);
        param.put("cols",colInfos);
        FmUtil.print("phpTipsUpd.ftl",param);
    }

    public static void createUpdFtl(String tbName,List<String> whereCols,List<ColInfo> colInfos){
        Map<String,Object> param=new HashMap<>();
        param.put("tbName",tbName);
        List<String> finalWhereCols = whereCols;
        param.put("updCols",colInfos.stream().filter(item->!finalWhereCols.contains(item.getColName())).collect(Collectors.toList()));
        /*StringBuilder strBud=new StringBuilder();
        colInfos.stream().filter(item->whereCols.contains(item.getColName())).forEach(item->{

        });*/
        param.put("whereCols",colInfos.stream().filter(item->finalWhereCols.contains(item.getColName())).collect(Collectors.toList()));
        //  校验输入的cols是否正确
        whereCols=new ArrayList<>(whereCols);
        for (ColInfo colInfo : colInfos) {
            if(whereCols.contains(colInfo.getColName())){
                whereCols.remove(colInfo.getColName());
            }
        }
        if(whereCols.size()>0){
            System.out.println("输入的whereCol不对:"+whereCols);
            throw new RuntimeException();
        }
        FmUtil.print("phpTipsUpd2.ftl",param);
    }

    @Data
    public static class StatusConst{
        //  值(int 或者 字符串)
        private Object val;
        //  英文名
        private String name;
        //  常数名
        private String constName;
        //  注释名(以及给前端的真实含义)
        private String meaning;

        public StatusConst(String dsl) {
            String[] arr = dsl.split(":");
            if(arr.length!=3){
                throw new RuntimeException("无法转换该注释"+dsl);
            }
            val=arr[0];
            name=arr[1];
            meaning=arr[2];
        }

        public static List<StatusConst> create(String str){
            str=str.replace("，",",");
            String[] arr = str.split(" ");
            List<StatusConst> list=new ArrayList<>(7);
            for (String s : arr) {
                list.add(new StatusConst(s));
            }
            return list;
        }

    }

    public static String htmlSpecialChars(ColInfo col,String content){
        /*if(col.getType().equals("varchar")){
            return "htmlspecialchars("+content+")";
        }else{
            return content;
        }*/
        return content;
    }

    public static String createMap(String name,List<ColInfo> colInfos){
        if(name==null){
            name="all";
        }
        StringBuilder strBud=new StringBuilder();
        /*strBud.append(String.format("$%s=[\n",name));
        for (ColInfo colInfo : colInfos) {
            if(colInfo.getColName().equals("id")||colInfo.getColName().equals("created_at")||colInfo.getColName().equals("updated_at")||colInfo.getColName().equals("status")){
                continue;
            }
            strBud.append(String.format("\t//\t%s\n",colInfo.getComment()));
            String str=String.format("\t'%s'=>\"\",\n",colInfo.getColName());
            strBud.append(str);
        }
        strBud.deleteCharAt(strBud.length()-2);
        strBud.append("];");*/
        strBud.append(String.format("$%s=[];\n",name));
        for (ColInfo colInfo : colInfos) {
            if(colInfo.getColName().equals("id")||colInfo.getColName().equals("created_at")||colInfo.getColName().equals("updated_at")||colInfo.getColName().equals("status")){
                continue;
            }
            //  strBud.append(String.format("\t//\t%s\n",colInfo.getComment()));
            String str=String.format("$%s['%s']=\"\";//\t%s\n",name,colInfo.getColName(),colInfo.getComment());
            strBud.append(str);
        }
        System.out.println(strBud.toString());
        return strBud.toString();
    }



}
